========================= uCOS Startup Walk Through ========================= This is walkthrough of a sample uCOS application. The application has three tasks using two mailboxes. The walkthrough starts with main follows the sequence of functions the lead to up to the running application. It's trimmed down to make it clearer the minimum sequences of steps and calls needed to make the application run. The first thing that runs is :doc:`crt.s ` which sets up the exception mode stacks and handlers. When it's finshed it jumps to main. .. code-block:: c //------------------------------------------------------------------------------------------------------------------- int main(void) { OSInit(); err = OSTaskCreate(AppTaskStart, (void*)0, (void*)&StartupStk[APP_TASK_START_STK_SIZE-1], APP_TASK_START_PRIO); OSStart(); } //------------------------------------------------------------------------------------------------------------------- void OSInit (void) { OSInitHookBegin(); /* Call port specific initialization code */ OS_InitMisc(); /* Initialize miscellaneous variables */ OS_InitRdyList(); /* Initialize the Ready List */ OS_InitTCBList(); /* Initialize the free list of OS_TCBs */ OS_InitEventList(); /* Initialize the free list of OS_EVENTs */ OS_FlagInit(); /* Initialize the event flag structures */ OS_MemInit(); /* Initialize the memory manager */ OS_QInit(); /* Initialize the message queue structures */ OS_InitTaskIdle(); /* Create the Idle Task */ OS_InitTaskStat(); /* Create the Statistic Task */ OSTmr_Init(); /* Initialize the Timer Manager */ OSInitHookEnd(); /* Call port specific init. code */ OSDebugInit(); } //------------------------------------------------------------------------------------------------------------------- INT8U OSTaskCreateExt (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio, INT16U id, OS_STK *pbos, INT32U stk_size, void *pext, INT16U opt) { // Allocate storage for CPU status register OS_CPU_SR cpu_sr = 0; OS_ENTER_CRITICAL(); /* Make sure we don't create the task from within an ISR */ if (OSIntNesting > 0) { OS_EXIT_CRITICAL(); return (OS_ERR_TASK_CREATE_ISR); } /* Make sure task doesn't already exist at this priority */ /* Reserve the priority to prevent others from doing ... */ /* ... the same thing until task is created. */ if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { OSTCBPrioTbl[prio] = OS_TCB_RESERVED; OS_EXIT_CRITICAL(); /* Clear the task stack (if needed) */ OS_TaskStkClr(pbos, stk_size, opt); // Initialize the task's stack psp = OSTaskStkInit(task, p_arg, ptos, opt); err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt); if (err == OS_ERR_NONE) { if (OSRunning == OS_TRUE) { /* Find HPT if multitasking has started */ OS_Sched(); } } else { OS_ENTER_CRITICAL(); OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Make this priority avail. to others */ OS_EXIT_CRITICAL(); } return (err); } OS_EXIT_CRITICAL(); return (OS_ERR_PRIO_EXIST); } //------------------------------------------------------------------------------------------------------------------- void OSStart (void) { if (OSRunning == OS_FALSE) { OS_SchedNew(); /* Find highest priority's task priority number */ OSPrioCur = OSPrioHighRdy; OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run */ OSTCBCur = OSTCBHighRdy; OSStartHighRdy(); /* Execute target specific code to start task */ } } //------------------------------------------------------------------------------------------------------------------- static void OS_SchedNew (void) { /* Find highest priority task */ } //------------------------------------------------------------------------------------------------------------------- OSStartHighRdy: // asm code // a) Calls OSTaskSwHook() // b) Sets OSRunning to TRUE // c) Switches to the highest priority task. //------------------------------------------------------------------------------------------------------------------- static void AppTaskStart (void *p_arg) { /* Create MBOXs for communication between Kbd and UserIF */ AppUserIFMbox1 = OSMboxCreate((void *)0); AppUserIFMbox2 = OSMboxCreate((void *)0); /* Create application tasks */ AppTaskCreate(); /* Task body, always written as an infinite loop. */ while (DEF_TRUE) { DoSomeWork(...); OSTimeDlyHMSM(0, 0, 0, 250); // Delay for 250 ms } } //------------------------------------------------------------------------------------------------------------------- static void AppTaskCreate (void) { // Create the application tasks OSTaskCreateExt(AppTaskUserIF, ....); OSTaskNameSet(APP_TASK_USER_IF_PRIO, "User I/F", &err); OSTaskCreateExt(AppTaskKbd, ....); OSTaskNameSet(APP_TASK_KBD_PRIO, "Keyboard", &err); OSTaskCreateExt(AppTaskFactorial, ...); OSTaskNameSet(APP_TASK_FACTORIAL_PRIO, "Factorial", &err); } //------------------------------------------------------------------------------------------------------------------- static void AppTaskKbd (void *p_arg) { // Monitor the state of the push buttons and passes messages to AppTaskUserIF() while (DEF_TRUE) { joystick = Joystick_GetStatus(); OSMboxPost(AppUserIFMbox1, (void *)joystick); OSTimeDly(OS_TICKS_PER_SEC / 10); } } //------------------------------------------------------------------------------------------------------------------- static void AppTaskUserIF (void *p_arg) { // LCD updating task // Initialize the LCD module PowerUp_LCD(NULL); while (DEF_TRUE) { msg = OSMboxPend(AppUserIFMbox1, OS_TICKS_PER_SEC / 10, &err); msg = OSMboxAccept(AppUserIFMbox2); Write_To_LCD_Cmd(msg); } } //------------------------------------------------------------------------------------------------------------------- static void AppTaskFactorial (void *p_arg) { // Busy task - calculating factorials for fun and profit UINT factorial; UINT i = 0; while (DEF_TRUE) { factorial = IntensiveAndExpensiveFactorial(i++ % 50); // Give others a chance to run OSTimeDlyHMSM(0, 0, 0, 100); } }